using System;
using System.Collections.Generic;
using UnityEngine;
using Yoozoo.Modules.InnerCity;

namespace WorldMapBase.LOD
{
    public class CastleLodBehavior : EntityLodBehavior
    {

        enum CastleLodStatus
        {
            EnterLOD0 = 0,
            ExitLOD0 = 1,
            UpdateScale = 2,
            ExitScale = 3,
        }
        
        // 建筑缩放曲线
        [SerializeField]
        private AnimationCurve _scaleCurve;

        [Header("建筑的最大缩放因子，控制建筑在Lod1时的大小比例")]
        [Range(0.1f,1.5f)]
        public float _scaleFactor = 0.52f;

        [Header("子建筑的默认缩放")]
        public float _defaultScaleFactor = 0.15f;
        
        [Header("建筑停止缩放的Lod百分比")]
        [Range(1,50)]
        public float _minLodPercent = 20;
        
        
        [Header("城墙缩放曲线")]
        public AnimationCurve wallScaleCurve;
        [Header("城墙最大时的缩放值")]
        public float wallMaxScale;
        [Header("城墙最小时的缩放值")]
        public float wallMinScale;

        private Vector3 lscale = Vector3.one;


        private static CastleLodStatus _lodStatus;
        
        private static List<LodCastle> _lodCastles = new List<LodCastle>(20);


        public static int _lastLodLevel = -1;
        public static float _lastLodPercent = -1;


        public static float _lastLinearValue = 1;
        public static float _lastScale = 0.52f;

        public static bool _lastRoadActive = false;
        public static bool _lastWallActiveStatus = false;
        
        private static float staticScaleFactor = 0.52f;
        private static float staticDefaultScaleFactor = 0.15f;
        
        private void Awake()
        {
            staticScaleFactor = _scaleFactor;
            staticDefaultScaleFactor = _defaultScaleFactor;
        }
        
        
        public override void OnUpdate()
        {
            for (int i = 0; i < _lodCastles.Count; i++)
            {
                _lodCastles[i].m_tile_collide.OnUpdate();
            }
        }

#if UNITY_EDITOR
        private void OnValidate()
        {
            staticScaleFactor = _scaleFactor;
            staticDefaultScaleFactor = _defaultScaleFactor;
        }
#endif


        public override void SyncConfig()
        {
            
        }
        
        public static void AddLodCastle(LodCastle lodCastle)
        {
            lodCastle.m_tile_collide.BuildingDefaultScale = staticScaleFactor;
            lodCastle.DefaultScaleFactor = staticDefaultScaleFactor;
            _lodCastles.Add(lodCastle);
            
            lodCastle.roadActiveStatus = _lastRoadActive;
            lodCastle.wallActiveStatus = _lastWallActiveStatus;

            switch (_lodStatus)
            {
                case CastleLodStatus.EnterLOD0:
                    LodBehaviorManager.CastleLodBehavior.OnEnterLOD0(lodCastle);
                    break;
                case CastleLodStatus.ExitLOD0:
                    LodBehaviorManager.CastleLodBehavior.OnExitLOD0(lodCastle);
                    break;
                case CastleLodStatus.UpdateScale:
                    LodBehaviorManager.CastleLodBehavior.OnUpdateScale(lodCastle);
                    break;
                case CastleLodStatus.ExitScale:
                    LodBehaviorManager.CastleLodBehavior.OnExitScale(lodCastle);
                    break;
            }

            LodBehaviorManager.CastleLodBehavior.UpdateLOD(lodCastle);
        }
        
        
        

        public static void RemoveLodCastle(LodCastle lodCastle)
        {
            _lodCastles.Remove(lodCastle);
        }
        
        
        public void SetWallScale(float factor)
        {
            float scale = wallScaleCurve.Evaluate(factor) * (wallMinScale - wallMaxScale) + wallMaxScale;
            lscale.x = scale;            
            lscale.y = scale;            
            lscale.z = scale;
            
            for (int i = 0; i < _lodCastles.Count; i++)
            {
                if (_lodCastles[i].wallScaleItem!=null)
                {
                    _lodCastles[i].wallScaleItem. transform.localScale = lscale;
                }
            }
        }


        private void UpdateLOD()
        {
            foreach (var lodCastle in _lodCastles)
            {
                UpdateLOD(lodCastle);
            }
        }

        private void UpdateLOD(LodCastle lodCastle)
        {
            lodCastle.UpdateLOD(_lastLodLevel,_lastLodPercent);
        }
        
        private void OnEnterLOD0()
        {
            _lodStatus = CastleLodStatus.EnterLOD0;
            
            _lastWallActiveStatus = true;
            // 显示城墙
            foreach (var lodCastle in _lodCastles)
            {
                OnEnterLOD0(lodCastle);
            }
        }

        private void OnEnterLOD0(LodCastle lodCastle)
        {
            lodCastle.wallActiveStatus = true;

            if (lodCastle.wallScaleItem!=null)
            {
                lodCastle.wallScaleItem.SetActive(true);
            }
        }
        

        private void OnExitLOD0()
        {
            _lodStatus = CastleLodStatus.ExitLOD0;
            _lastWallActiveStatus = false;
            // 隐藏城墙
            foreach (var lodCastle in _lodCastles)
            {
                OnExitLOD0(lodCastle);
            }
        }


        private void OnExitLOD0(LodCastle lodCastle)
        {
            lodCastle.wallActiveStatus = false;
            if (lodCastle.wallScaleItem != null)
            {
                lodCastle.wallScaleItem.SetActive(false);
            }
        }

        private void OnUpdateScale(float curveValue, float scaleValue)
        {
            _lodStatus = CastleLodStatus.UpdateScale;
            
            _lastLinearValue = curveValue;
            _lastScale = scaleValue;
            _lastRoadActive = false;

            // 缩放建筑
            foreach (var lodCastle in _lodCastles)
            {
                OnUpdateScale(lodCastle);
            }
        }


        private void OnUpdateScale(LodCastle lodCastle)
        {
            lodCastle.SetWallScale(_lastLinearValue);
            lodCastle.m_tile_collide.SetScale(_lastLinearValue,_lastScale);

            if (lodCastle.roadActiveStatus)
            {
                lodCastle.SetRoadActiveStatus(false);
            }
        }

        private void OnExitScale()
        {
            _lodStatus = CastleLodStatus.ExitScale;
            
            _lastLinearValue = 0;
            _lastScale = _defaultScaleFactor;
            _lastRoadActive = true;
            
            // 所有建筑显示、缩放为默认缩放
            foreach (var lodCastle in _lodCastles)
            {
                OnExitScale(lodCastle);
            }
            
        }

        private void OnExitScale(LodCastle lodCastle)
        {
            lodCastle.m_tile_collide.OnExitScale(_lastLinearValue,_defaultScaleFactor);
            lodCastle.SetWallScale(_lastLinearValue);
            lodCastle.SetRoadActiveStatus(true);
        }
        
        
        public override void OnUpdateLodLevel(int level, int lastLevel)
        {

        }

        public override void OnUpdateLodPercent(int lodLevel, float lodPercent)
        {
            
            bool tmp = false;
            if (_lastLodLevel != lodLevel)
            {
                // lod切换了
                
                // 0-->1
                if (_lastLodLevel == 0)
                {
                    lodPercent = 100;
                    tmp = true;
                    OnExitLOD0();
                }

                if (lodLevel == 0)
                {
                    OnEnterLOD0();
                }
            }



            if (lodLevel > 0 && !tmp)
            {
                _lastLodLevel = lodLevel;
                _lastLodPercent = lodPercent;
                UpdateLOD();
                return;
            }
            
            
            if (lodPercent <= _minLodPercent)
            {
                if (_lastLodPercent > _minLodPercent)
                {
                    OnExitScale();
                }

                if (_lastLodPercent < 0)
                {
                    OnUpdateScale(1, _defaultScaleFactor);
                }
            }
            else
            {
                float curveFactor = (lodPercent - _minLodPercent) / (100 - _minLodPercent); // 线性值

                float curveValue = _scaleCurve.Evaluate(curveFactor);
                curveValue = Mathf.Min(1, Mathf.Max(0, curveValue)); // 转为曲线值（缩放、位移比例）

                float scaleValue = (_scaleFactor - _defaultScaleFactor) * curveValue + _defaultScaleFactor; // 建筑真正的缩放值
                
                OnUpdateScale(curveValue,scaleValue);
            }

            
            _lastLodLevel = lodLevel;
            _lastLodPercent = lodPercent;
            UpdateLOD();
        }
    }
}